package com.crois.barrier.admin.controller;


import com.crois.barrier.admin.dto.ApiRouteInfoDto;
import com.crois.barrier.admin.entity.*;
import com.crois.barrier.admin.enums.PositionTypeEnum;
import com.crois.barrier.admin.mapstruct.ApiRouteInfoDtoEntityMapper;
import com.crois.barrier.admin.resp.BarrierResponseWrapper;
import com.crois.barrier.admin.service.*;
import com.crois.barrier.common.utils.UtilsAndCommons;
import com.crois.barrier.common.response.BarrierResponseEntity;
import com.zhimydou.ztools.collection.CollectionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: HouZeYu
 * @Description:
 * @Date: Created in 12:12 2021/10/25
 */

@RequestMapping(UtilsAndCommons.DEFAULT_BARRIER_ADMIN_API_ROUTE_CONTEXT)
@RestController
public class ApiRouteCtl {


    @Autowired
    @Qualifier("apiRouteInfoSvc")
    private IApiRouteInfoSvc apiRouteInfoSvc;

    @Autowired
    @Qualifier("apiRouteGroupSvc")
    private IApiRouteGroupSvc apiRouteGroupSvc;

    @Autowired
    @Qualifier("apiParameterInfoSvc")
    private IApiParameterInfoSvc apiParameterInfoSvc;

    @Autowired
    @Qualifier("apiResponseInfoSvc")
    private IApiResponseInfoSvc apiResponseInfoSvc;

    @Autowired
    @Qualifier("apiFailCodeInfoSvc")
    private IApiFailCodeInfoSvc apiFailCodeInfoSvc;

    @Autowired
    @Qualifier("ipAndWeightSvc")
    private IIpAndWeightSvc ipAndWeightSvc;


    @Autowired
    @Qualifier("pluginDataSvc")
    private IPluginDataSvc pluginDataSvc;

    /***
     * barrier api route list
     */
    @GetMapping(UtilsAndCommons.BARRIER_LIST_CONTEXT)
    public BarrierResponseEntity<List<?>> apiRouteList(@RequestParam(value = "apiRouteName",required = false) String apiRouteName,
                                                       @RequestParam(value = "apiGroupId",required = false) Integer apiGroupId){

        List<ApiRouteInfo> apiRouteInfoList = apiRouteInfoSvc.findApiRouteList(apiRouteName,apiGroupId);

        if (CollectionUtil.isNotEmpty(apiRouteInfoList)) {
            for (ApiRouteInfo apiRouteInfo : apiRouteInfoList) {
                ApiRouteGroup apiRouteGroup = apiRouteGroupSvc.getById(apiRouteInfo.getApiRouteGroupId());
                apiRouteInfo.setApiGroupName(apiRouteGroup.getApiRouteGroupName());
            }
        }
        return BarrierResponseWrapper.okList(ApiRouteInfoDtoEntityMapper.INSTANCE.toApiRouteInfoDtoList(apiRouteInfoList));

    }


    /***
     * barrier api route detail
     */
    @GetMapping(UtilsAndCommons.BARRIER_DETAIL_CONTEXT+"/{apiRouteId}")
    public BarrierResponseEntity<?> apiRouteDetail(@PathVariable("apiRouteId") Integer apiRouteId){
        ApiRouteInfo apiRouteInfo = apiRouteInfoSvc.getById(apiRouteId);
        List<IpAndWeight> ipAndWeightList = ipAndWeightSvc.getIpAndWeightListByRouteId(apiRouteInfo.getId());
        apiRouteInfo.setIpList(ipAndWeightList);
        ApiRouteGroup apiRouteGroup = apiRouteGroupSvc.getById(apiRouteInfo.getApiRouteGroupId());
        apiRouteInfo.setApiGroupName(apiRouteGroup.getApiRouteGroupName());
        List<ApiParameterInfo> apiParameterInfoList = apiParameterInfoSvc.findApiParameterListByRouteIdAndType(PositionTypeEnum.API_PARAMETER.getType(),apiRouteInfo.getId());
        apiRouteInfo.setApiParameter(apiParameterInfoList);
        List<ApiParameterInfo> constantsParameterInfoList = apiParameterInfoSvc.findApiParameterListByRouteIdAndType(PositionTypeEnum.CONSTANTS.getType(),apiRouteInfo.getId());
        apiRouteInfo.setConstantsParameter(constantsParameterInfoList);
        ApiResponseInfo apiResponseInfo = apiResponseInfoSvc.findApiResponseInfoByRouteId(apiRouteInfo.getId());
        if (!Objects.isNull(apiResponseInfo)){
            List<ApiFailCodeInfo> apiFailCodeInfoList =  apiFailCodeInfoSvc.findApiFailCodeInfoListByApiResponseInfoId(apiResponseInfo.getId());
            apiResponseInfo.setApiFailCodeInfoList(apiFailCodeInfoList);
        }
        List<PluginData> routePluginList = pluginDataSvc.findRoutePluginList(apiRouteInfo.getId());
        if (CollectionUtil.isNotEmpty(routePluginList)){
            List<String> plugins = routePluginList.stream().map(PluginData::getName).collect(Collectors.toList());
            apiRouteInfo.setPlugins(plugins);
        }
        apiRouteInfo.setApiResponse(apiResponseInfo);
        return BarrierResponseWrapper.ok(ApiRouteInfoDtoEntityMapper.INSTANCE.toApiRouteInfoDto(apiRouteInfo));
    }

    /***
     * barrier route env publish
     */
    @PostMapping(UtilsAndCommons.BARRIER_ENV_CONTEXT+"/{apiRouteId}"+"/{env}")
    public BarrierResponseEntity<Void> publishRouteEnv(@PathVariable("apiRouteId") Integer apiRouteId
                                                  ,@PathVariable("env") String env){
        ApiRouteInfo apiRouteInfo = new ApiRouteInfo();
        apiRouteInfo.setId(apiRouteId);
        if (env.equals("PROD")){
            apiRouteInfo.setEnvProdPublish(true);
        }else if (env.equals("BETA")) {
            apiRouteInfo.setEnvBetaPublish(true);
        }else if (env.equals("TEST")) {
            apiRouteInfo.setEnvTestPublish(true);
        }
        apiRouteInfoSvc.updateRoutePush(apiRouteInfo);
        return BarrierResponseWrapper.ok();
    }

    /***
     * barrier route env delete
     */
    @DeleteMapping(UtilsAndCommons.BARRIER_ENV_CONTEXT+"/{apiRouteId}"+"/{env}")
    public BarrierResponseEntity<Void> deleteRouteEnv(@PathVariable("apiRouteId") Integer apiRouteId
            ,@PathVariable("env") String env){
        ApiRouteInfo apiRouteInfo = new ApiRouteInfo();
        apiRouteInfo.setId(apiRouteId);
        if (env.equals("PROD")){
            apiRouteInfo.setEnvProdPublish(false);
        }else if (env.equals("BETA")) {
            apiRouteInfo.setEnvBetaPublish(false);
        }else if (env.equals("TEST")) {
            apiRouteInfo.setEnvTestPublish(false);
        }
        apiRouteInfoSvc.updateRoutePush(apiRouteInfo);
        return BarrierResponseWrapper.ok();
    }

    /***
     * barrier api route update
     */
    @PutMapping(UtilsAndCommons.BARRIER_UPDATE_CONTEXT+"/{apiRouteId}")
    public BarrierResponseEntity<Void> apiRouteUpdate(@PathVariable("apiRouteId") Integer apiRouteId,@RequestBody ApiRouteInfoDto apiRouteInfoDto){
        apiRouteInfoDto.setId(apiRouteId);
        apiRouteInfoSvc.updateRoute(ApiRouteInfoDtoEntityMapper.INSTANCE.toApiRouteInfoEntity(apiRouteInfoDto));
        return BarrierResponseWrapper.ok();
    }

    /***
     * barrier api route save
     */
    @PostMapping(UtilsAndCommons.BARRIER_ADD_CONTEXT)
    public BarrierResponseEntity<Void> apiRouteAdd(@RequestBody ApiRouteInfoDto apiRouteGroupDto){
        apiRouteInfoSvc.saveRoute(ApiRouteInfoDtoEntityMapper.INSTANCE.toApiRouteInfoEntity(apiRouteGroupDto));
        return BarrierResponseWrapper.ok();
    }

}
